//
// Copyright © 2025 Stream.io Inc. All rights reserved.
//

import XCTest

/// Asserts the provided `Result` object is `.success(referenceValue)`.
///
/// - Parameters:
///   - result: The Result object under tests.
///   - referenceValue: The reference success value.
public func AssertResultSuccess<T: Equatable, E: Error>(
    _ result: Result<T, E>,
    _ referenceValue: T,
    file: StaticString = #filePath,
    line: UInt = #line
) {
    if case let .success(value) = result {
        XCTAssertEqual(value, referenceValue, file: file, line: line)
    } else {
        XCTFail("Expected .success, got \(result).", file: file, line: line)
    }
}

/// Asserts the provided `Result` object is `.failure(referenceError)`.
///
/// - Parameters:
///   - result: The Result object under tests.
///   - referenceError: The reference failure value.
///
/// - Warning: ⚠️ Because the `Error` type is not `Equatable`, it compares the error objects
///   based on their description generated by `String(describing:)`.
public func AssertResultFailure<T: Equatable, E: Error>(
    _ result: Result<T, E>,
    _ referenceError: Error,
    file: StaticString = #filePath,
    line: UInt = #line
) {
    if case let .failure(error) = result {
        XCTAssertEqual(String(describing: error), String(describing: referenceError), file: file, line: line)
    } else {
        XCTFail("Expected .failure, got \(result).", file: file, line: line)
    }
}

/// Asserts the provided `Result` object is `.failure(referenceError)`.
///
/// - Parameters:
///   - result: The Result object under tests.
///   - referenceError: The reference failure value.
public func AssertResultFailure<T, E: Error & Equatable>(
    _ result: Result<T, E>,
    _ referenceError: E,
    file: StaticString = #filePath,
    line: UInt = #line
) {
    if case let .failure(error) = result {
        XCTAssertEqual(error, referenceError, file: file, line: line)
    } else {
        XCTFail("Expected .failure, got \(result).", file: file, line: line)
    }
}
